using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace Perovich.GameObjects.TwoDimensional
{
    

    /// <summary>
    /// The <see cref="DrawableObject2D"/> is a <see cref="GameObject"/>, that is an abstract base class for any object that exists in two dimensions.
    /// </summary>
    public class DrawableObject2D : GameObject
    {

        private Vector2 _position;
        private Vector2 _speed;
        private Vector2 _accel;
        private Vector2 LastPos;



        private float _rotation;

        /// <summary>
        /// Gets or sets the rotation of the <see cref="DrawableObject2D"/>.
        /// </summary>
        public float Rotation
        {
            get { return _rotation; }
            set
            {
                float old = _rotation;
                _rotation = value;
                if (_rotation != old)
                    SignalRotationChanged();
            }
        }

        /// <summary>
        /// Triggered whenever the <see cref="DrawableObject2D.Rotation"/> property changes.
        /// </summary>
        public event EventHandler RotationChanged;

        void SignalRotationChanged()
        {
            if (RotationChanged != null)
            {
                RotationChanged(this, null);
            }
        }


        

        

        /// <summary>
        /// Gets or sets the position of this <see cref="DrawableObject2D"/>.
        /// </summary>
        public Vector2 Position
        {
            get { return _position; }
            set { _position = value; }
        }

        /// <summary>
        /// Gets or sets the velocity of this <see cref="DrawableObject2D"/>.
        /// </summary>
        public Vector2 Velocity
        {
            get { return _speed; }
            set { _speed = value; }
        }

        /// <summary>
        /// Gets or sets the acceleration of this <see cref="DrawableObject2D"/>.
        /// </summary>
        public Vector2 Acceleration
        {
            get { return _accel; }
            set { _accel = value; }
        }





        /// <summary>
        /// Constructs a new instance of the <see cref="DrawableObject2D"/> class.
        /// </summary>
        /// <param name="game"><see cref="Perovich.GameObjects.Interfaces.ICanHoldComponents"/> instance that this <see cref="DrawableObject2D"/> will be constructed for.</param>
        public DrawableObject2D(Interfaces.ICanHoldComponents game)
            : base(game)
        {
            _position = Vector2.Zero;
            _speed = Vector2.Zero;
            _accel = Vector2.Zero;
            Scale = 1;
            Rotation = 0;
            Active = true;
        }



        /// <summary>
        /// Allows the <see cref="DrawableObject2D"/> to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            if (gameTime == null)
                throw new ArgumentNullException("gameTime");
            LastPos = _position;
            _position += _speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
            _speed += _accel * (float)gameTime.ElapsedGameTime.TotalSeconds;
            base.Update(gameTime);
        }

        /// <summary>
        /// Returns the <see cref="DrawableObject2D"/> to the position it was in before the Last Update.
        /// </summary>
        /// <example>This method can be called inside a collision handler do return the object to its position just before the collision.</example>
        public void Backup()
        {
            _position = LastPos;
        }

    }
}
